# -*- mode: org; fill-column: 80; -*-
#+TITLE: REST API Example
#+AUTHOR: Zelphir Kaltstahl
#+EMAIL: zelphirkaltstahl@posteo.de
#+STARTUP: content indent align inlineimages hideblocks entitiesplain nologdone nologreschedule nologredeadline nologrefile
#+TODO: TODO WIP DEPRECATED | DONE
#+DATE: [2023-03-02 Do]
#+KEYWORDS: emacs org example
#+LANGUAGE: English
#+PRIORITIES: A E E
#+EXCLUDE_TAGS: noexport
#+OPTIONS: ^:{}
#+OPTIONS: H:10
#+OPTIONS: toc:2
#+OPTIONS: tags:nil
#+OPTIONS: tasks:t
#+OPTIONS: H:6
#+OPTIONS: p:nil
#+OPTIONS: pri:nil
#+OPTIONS: prop:nil
#+OPTIONS: todo:t
#+OPTIONS: stat:nil
#+OPTIONS: |:t
#+OPTIONS: inline:nil
#+OPTIONS: date:t

* Disable confirmation of execution of org source blocks

#+begin_src elisp
(setq org-babel-confirm-evaluate nil)
#+end_src

#+RESULTS:

* Prerequisites
:PROPERTIES:
:CUSTOM_ID: prerequisites
:END:

#+name: prerequisites
#+begin_src sh :results replace drawer :exports both :dir "/sudo::" :eval never-export
DEBIAN_FRONTEND=noninteractive apt-get --yes --quiet install jq
#+end_src

#+RESULTS: prerequisites
:results:
Reading package lists...
Building dependency tree...
Reading state information...
jq is already the newest version (1.6-2.1ubuntu3).
The following packages were automatically installed and are no longer required:
  libflashrom1 libftdi1-2 libllvm13 wireguard-tools
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 8 not upgraded.
:end:

* Global properties
:PROPERTIES:
:header-args: :tangle example.sh :comments link
:header-args:sh: :results replace drawer :shebang "#!/bin/bash" :exports both :eval never-export
:END:

** Get JSON from an API
:PROPERTIES:
:CUSTOM_ID: get-json
:END:

#+begin_src sh :results verbatim :var URL="https://reqres.in/api/users" :var PAGE="1" :wrap src json
curl -s "${URL}?page=${PAGE}" -H "Content-Type: application/json" \
    | jq
#+end_src

#+RESULTS:
#+begin_src json
{
  "page": 1,
  "per_page": 6,
  "total": 12,
  "total_pages": 2,
  "data": [
    {
      "id": 1,
      "email": "george.bluth@reqres.in",
      "first_name": "George",
      "last_name": "Bluth",
      "avatar": "https://reqres.in/img/faces/1-image.jpg"
    },
    {
      "id": 2,
      "email": "janet.weaver@reqres.in",
      "first_name": "Janet",
      "last_name": "Weaver",
      "avatar": "https://reqres.in/img/faces/2-image.jpg"
    },
    {
      "id": 3,
      "email": "emma.wong@reqres.in",
      "first_name": "Emma",
      "last_name": "Wong",
      "avatar": "https://reqres.in/img/faces/3-image.jpg"
    },
    {
      "id": 4,
      "email": "eve.holt@reqres.in",
      "first_name": "Eve",
      "last_name": "Holt",
      "avatar": "https://reqres.in/img/faces/4-image.jpg"
    },
    {
      "id": 5,
      "email": "charles.morris@reqres.in",
      "first_name": "Charles",
      "last_name": "Morris",
      "avatar": "https://reqres.in/img/faces/5-image.jpg"
    },
    {
      "id": 6,
      "email": "tracey.ramos@reqres.in",
      "first_name": "Tracey",
      "last_name": "Ramos",
      "avatar": "https://reqres.in/img/faces/6-image.jpg"
    }
  ],
  "support": {
    "url": "https://reqres.in/#support-heading",
    "text": "To keep ReqRes free, contributions towards server costs are appreciated!"
  }
}
#+end_src

** POST data to an API and get the response
:PROPERTIES:
:CUSTOM_ID: post-json
:END:

#+NAME: prepare-data
#+begin_src sh :results verbatim :var USERNAME="morpheus" :var JOB="bar"
read -r -d '' DATA <<EOF
{
    "name": "${USERNAME}",
    "job": "${JOB}"
}
EOF
printf "%s" "${DATA}"
#+end_src

#+NAME: send-request
#+begin_src sh :results verbatim :wrap src json :var DATA=prepare-data() :var URL="https://reqres.in/api/users"
curl \
    --request POST \
    --silent "${URL}" \
    --header "Content-Type: application/json" \
    --data "${DATA}" \
    | jq
#+end_src

#+RESULTS: send-request
#+begin_src json
{
  "name": "morpheus",
  "job": "bar",
  "id": "243",
  "createdAt": "2023-03-03T00:46:58.926Z"
}
#+end_src

** POST to login

*** Not exported credentials                                     :noexport:

#+NAME: example-login-prepare-data
#+begin_src sh :results verbatim :var EMAIL="eve.holt@reqres.in" :var PASSWORD="cityslicka"
read -r -d '' CREDENTIALS <<EOF
{
    "email": "${EMAIL}",
    "password": "${PASSWORD}"
}
EOF
printf "%s" "${CREDENTIALS}"
#+end_src

*** Usage

**** Get token

#+NAME: example-login-send-request
#+begin_src sh :results verbatim :var CREDENTIALS=example-login-prepare-data() :var URL="https://reqres.in/api/login"
curl \
    --request POST \
    --silent "${URL}" \
    --header "Content-Type: application/json" \
    --data "${CREDENTIALS}" \
    | jq -r ".token"
#+end_src

#+RESULTS: example-login-send-request
:results:
QpwL5tke4Pnpja7X4
:end:

**** WIP Use token

This does not work, because the API does not respond with a good answer, when we set the authorization header.

#+NAME: example-login-send-logged-in-request
#+begin_src sh :results verbatim :var TOKEN=example-login-send-request() :var URL="https://reqres.in/api/users" :var PAGE="2"
# printf "token: %s\n" "${TOKEN}"
curl \
    --request GET \
    --silent "${URL}?page=${PAGE}" \
    --header "Content-Type: application/json" \
    --header "Authorization: Basic ${TOKEN}" \
    | jq
#+end_src

#+RESULTS: example-login-send-logged-in-request
:results:
:end:
